package twoD.IsoPfem.EmbeddedCrackModel;

import inf.jlinalg.SolveFailedException;
import inf.v3d.view.Viewer;

import java.util.ArrayList;

import twoD.IsoPfem.Constraint;
import twoD.IsoPfem.Force;
import twoD.IsoPfem.IGeometry;
import twoD.IsoPfem.ElasticStructure;
import twoD.IsoPfem.Mesh;
import twoD.IsoPfem.MeshLibrary;
import twoD.IsoPfem.Node;
import twoD.IsoPfem.RealTable;
import twoD.IsoPfem.Visualizer;
import twoD.IsoPfem.Control.ArcLengthController;
import twoD.IsoPfem.Control.DisplacementConstraintCondition;
import twoD.IsoPfem.Control.IConstraintCondition;
import twoD.IsoPfem.Control.LoadConstraintCondition;
import twoD.IsoPfem.Control.SphereConstraintCondition;
import twoD.IsoPfem.utils.NodeUtilities;

public class BeamDemo {

	/**
	 * function to visualize the structure
	 * 
	 * @param struct
	 */
	public void Visualize(ElasticStructure struct) {
		Viewer view = new Viewer();
		Visualizer viz = new Visualizer(struct, view);
		viz.automaticScale();
		viz.drawConstraints();
		viz.drawForces();
		viz.drawEdgeLoads();
		viz.drawElements();
		view.setVisible(true);
	}

	/**
	 * function to draw structure with cracks
	 * 
	 * @param struct
	 */
	public void VisualizeWithCrack(CrackStructure struct) {
		Viewer view = new Viewer();
		CrackVisualizer viz = new CrackVisualizer(struct, view);
		viz.automaticScale();
		viz.drawConstraints();
		viz.drawForces();
		viz.drawEdgeLoads();
		// viz.drawElements();
		viz.drawCrack();
		viz.drawSigma11();
		viz.showElementId();
		// viz.drawDisplacedStructure();
		view.setVisible(true);
	}

	public void crackTest1() {
		Mesh M = MeshLibrary
				.createTriangleMeshFromGiD("D:/Giang/vgu/zWork/simple_beam3_notip.gid/mesh1.txt");

		double E = 30e9;
		double nu = 0.18;
		double ft = 2.9e6;
		double Gf = 140;
		double r = 1e5;
		double s = 1e-3;
		double psi = 1e-3;
		int lambda0 = 3;
		int N = 21;

		// double E = 30e6;
		// double nu = 0.18;
		// double ft = 2.9e3;
		// double Gf = 0.14;
		// double r = 1e2;
		// double s = 1e-3;
		// double psi = 2e-3;
		// int lambda0 = 18;
		// int N = 6;

		double Dnn = 0.01 * E;
		double Dss = 0.01 * E;

		RealTable realTable = new RealTable(E, nu, Dnn, Dss);
		realTable.setThickness(1);
		realTable.setTensileStrength(ft);
		realTable.setFractureEnergy(Gf);

		CrackStructure cStruct = MeshLibrary.createEmbededCrackModel(realTable,
				M);

		Constraint c1 = new Constraint(false, false);

		ArrayList<Node> constraintedEdge = NodeUtilities.findNodeOnLine(
				cStruct, 1, 0, 0);
		for (Node n : constraintedEdge)
			n.setConstraint(c1);

		Force f = new Force(0, -r);
		ArrayList<Node> forcedEdge = NodeUtilities.findNodeOnLine(cStruct, 1,
				0, -100);
		for (Node n : forcedEdge)
			n.setForce(f);

		// IConstraintCondition cc1 = new LoadConstraintCondition(1, 0.1);
		IConstraintCondition cc2 = new DisplacementConstraintCondition(4.5e-3,
				1e-4, NodeUtilities.findNode(cStruct, 100, 0).get(0)
						.getDofNumbers()[1]);
		IConstraintCondition cc3 = new SphereConstraintCondition(
				s,
				psi,
				NodeUtilities.findNode(cStruct, 100, 0).get(0).getDofNumbers()[1]);
		cc3.setInitialLambda(lambda0);

		ArcLengthController C = new ArcLengthController(cStruct, cc3);
		C.setNumberOfStep(N);
		try {
			C.Iterate();
		} catch (SolveFailedException e) {
			e.printStackTrace();
		}
		// C.listingState();

		VisualizeWithCrack(cStruct);
	}

	public void crackTest2() {
		Mesh M = MeshLibrary
				.createTriangleMeshFromGiD("D:/Giang/vgu/zWork/simple_beam3_notip.gid/mesh2.txt");

		double E = 30e9;
		double nu = 0.18;
		double Dnn = 0.01 * E;
		double Dss = 0.01 * E;

		RealTable realTable = new RealTable(E, nu, Dnn, Dss);
		realTable.setThickness(1);
		realTable.setTensileStrength(3.5e6);
		realTable.setTensileStrength(2.9e6);
		realTable.setFractureEnergy(140);

		CrackStructure cStruct = MeshLibrary.createEmbededCrackModel(realTable,
				M);

		Constraint c1 = new Constraint(false, false);
		Constraint c2 = new Constraint(false, true);
		Constraint c3 = new Constraint(true, false);

		// ArrayList<Node> constraintedEdge = NodeUtilities.findNodeOnLine(
		// cStruct, 1, 0, 0);
		// for (Node n : constraintedEdge)
		// n.setConstraint(c1);

		NodeUtilities.findNode(cStruct, 0, 0).get(0).setConstraint(c1);
		NodeUtilities.findNode(cStruct, 0, 1).get(0).setConstraint(c2);
//		NodeUtilities.findNode(cStruct, 1, 0).get(0).setConstraint(c3);

		Force f = new Force(1e5, 0);
		ArrayList<Node> forcedEdge = NodeUtilities.findNodeOnLine(cStruct, 1,
				0, -1);
		// ArrayList<Node> forcedEdge = NodeUtilities.findNode(cStruct, 1, 0);
		for (Node n : forcedEdge)
			n.setForce(f);

		// IConstraintCondition cc1 = new LoadConstraintCondition(1, 0.1);
		// IConstraintCondition cc2 = new DisplacementConstraintCondition(1e-3,
		// 5e-4, NodeUtilities.findNode(cStruct, 100, 0).get(0)
		// .getDofNumbers()[1]);
		IConstraintCondition cc3 = new SphereConstraintCondition(1e-5, 0,
				NodeUtilities.findNode(cStruct, 1, 0).get(0).getDofNumbers()[1]);
		cc3.setInitialLambda(1);

		ArcLengthController C = new ArcLengthController(cStruct, cc3);
		C.setNumberOfStep(10);
		try {
			C.Iterate();
		} catch (SolveFailedException e) {
			e.printStackTrace();
		}
		// C.listingState();

		VisualizeWithCrack(cStruct);
	}
	
	public void crackTest3() {
		Mesh M = MeshLibrary
				.createTriangleMeshFromGiD("D:/Giang/vgu/zWork/simple_beam3_notip.gid/mesh4.txt");

		double E = 30e9;
		double nu = 0.18;
		double ft = 2.9e6;
		double Gf = 140;
		double r = 2e6;
		double s = 1e-3;
		double psi = 1e-3;
		int lambda0 = 60;
		int N = 12;

		// double E = 30e6;
		// double nu = 0.18;
		// double ft = 2.9e3;
		// double Gf = 0.14;
		// double r = 1e2;
		// double s = 1e-3;
		// double psi = 2e-3;
		// int lambda0 = 18;
		// int N = 6;

		double Dnn = 0.01 * E;
		double Dss = 0.01 * E;

		RealTable realTable = new RealTable(E, nu, Dnn, Dss);
		realTable.setThickness(1);
		realTable.setTensileStrength(ft);
		realTable.setFractureEnergy(Gf);

		CrackStructure cStruct = MeshLibrary.createEmbededCrackModel(realTable,
				M);

		Constraint c1 = new Constraint(false, false);

		ArrayList<Node> constraintedEdge = NodeUtilities.findNodeOnLine(
				cStruct, 1, 0, 0);
		for (Node n : constraintedEdge)
			n.setConstraint(c1);

		Force f = new Force(r, 0);
		ArrayList<Node> forcedEdge = NodeUtilities.findNodeOnLine(cStruct, 1,
				0, -100);
		for (Node n : forcedEdge)
			n.setForce(f);

		// IConstraintCondition cc1 = new LoadConstraintCondition(1, 0.1);
		IConstraintCondition cc2 = new DisplacementConstraintCondition(4.5e-3,
				5e-6, NodeUtilities.findNode(cStruct, 100, 50).get(0)
						.getDofNumbers()[1]);
		IConstraintCondition cc3 = new SphereConstraintCondition(
				s,
				psi,
				NodeUtilities.findNode(cStruct, 100, 50).get(0).getDofNumbers()[1]);
		cc3.setInitialLambda(lambda0);

		ArcLengthController C = new ArcLengthController(cStruct, cc3);
		C.setNumberOfStep(N);
		try {
			C.Iterate();
		} catch (SolveFailedException e) {
			e.printStackTrace();
		}
		// C.listingState();

		VisualizeWithCrack(cStruct);
	}

	public static void main(String[] args) {
		new BeamDemo().crackTest3();
	}

}
